#include "io_manager.h"
#include "file_output_strategy.h"

namespace Base {
namespace SystemLog {
ErrCode IOManager::AddStrategy(OutputStrategyPtr strategy) {
    if (!strategy) {
        return ERR_INVALID_ARGUMENT;
    }

    std::lock_guard<std::mutex> lock(mutex_);
    strategies_.push_back(std::move(strategy));
    return ERR_OK;
}

ErrCode IOManager::Write(const char* data, size_t len) {
    std::lock_guard<std::mutex> lock(mutex_);
    ErrCode finalCode = ERR_OK;
    for (auto& strategy : strategies_) {
        ErrCode code = strategy->Write(data, len);
        if (code != ERR_OK && finalCode == ERR_OK) {
            finalCode = code;
        }
    }

    return finalCode;
}

ErrCode IOManager::Flush() {
    std::lock_guard<std::mutex> lock(mutex_);
    ErrCode finalCode = ERR_OK;

    for (auto& strategy : strategies_) {
        ErrCode code = strategy->Flush();
        if (code != ERR_OK && finalCode == ERR_OK) {
            finalCode = code;
        }
    }

    return finalCode;
}

ErrCode IOManager::Close() {
    std::lock_guard<std::mutex> lock(mutex_);
    ErrCode finalCode = ERR_OK;

    for (auto& strategy : strategies_) {
        ErrCode code = strategy->Close();
        if (code != ERR_OK && finalCode == ERR_OK) {
            finalCode = code;
        }
    }

    strategies_.clear();
    return finalCode;
}

ErrCode IOManager::ForceSync() {
    std::lock_guard<std::mutex> lock(mutex_);
    ErrCode finalCode = ERR_OK;

    for (auto& strategy : strategies_) {
        // 尝试将策略转换为FileOutputStrategy以调用ForceSync
        auto fileStrategy = dynamic_cast<FileOutputStrategy*>(strategy.get());
        if (fileStrategy) {
            ErrCode code = fileStrategy->ForceSync();
            if (code != ERR_OK && finalCode == ERR_OK) {
                finalCode = code;
            }
        } else {
            // 对于其他策略，调用普通的Flush
            ErrCode code = strategy->Flush();
            if (code != ERR_OK && finalCode == ERR_OK) {
                finalCode = code;
            }
        }
    }

    return finalCode;
}
} // namespace SystemLog
} // namespace Base
